/**
 * Notes: 项目状态历史数据模型
 * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)
 * Date: 2023-08-30 19:20:00
 */

const BaseModel = require('../../../framework/platform/model/base_model.js');
const util = require('../../../framework/helpers/util.js');
const dataUtil = require('../../../framework/helpers/data_util.js');
const timeUtil = require('../../../framework/helpers/time_util.js');

class ProjectStateHistoryModel extends BaseModel {

	/** 构造函数 */
	constructor() {
		super();
		
		// 设置集合名
		this.setCollectionName('project_state_history');
		
		// 字段定义
		this.DB_STRUCTURE = {
			_pid: 'string|true',      // 项目ID (系统保留，不修改)
			
			// 基础关联信息
			projectId: 'string|true',   // 关联的项目ID
			branchId: 'string|true',    // 关联的分支ID
			
			// 状态信息
			fromState: 'object|true',   // 转换前的状态
			toState: 'object|true',     // 转换后的状态
			eventType: 'string|true',   // 事件类型
			
			// 转换前的状态细节
			fromLevel1: 'int|true',      // 转换前一级状态
			fromLevel2: 'string|false',  // 转换前二级状态
			fromLevel3: 'string|false',  // 转换前三级状态
			fromLevel4: 'string|false',  // 转换前四级状态
			
			// 转换后的状态细节
			toLevel1: 'int|true',        // 转换后一级状态
			toLevel2: 'string|false',    // 转换后二级状态
			toLevel3: 'string|false',    // 转换后三级状态
			toLevel4: 'string|false',    // 转换后四级状态
			
			// 备注和关联资料
			comment: 'string|false',     // 状态转换备注
			attachments: 'array|false',  // 关联附件
			
			// 时间和用户信息
			createdBy: 'string|true',    // 操作者ID
			createdByName: 'string|true', // 操作者姓名
			createdTime: 'int|true'      // 创建时间
		};
	}

	// 静态集合名称
	static get CL() {
		return this.C('project_state_history');
	}

	/**
	 * 添加状态历史记录
	 * @param {Object} data 状态历史数据
	 * @returns {Promise<String>} 创建的记录ID
	 */
	async addStateHistory(data) {
		try {
			console.log('[addStateHistory] 开始添加状态历史记录:', JSON.stringify(data, null, 2));
			
			// 确保必填字段
			if (!data.projectId) {
				throw new Error('缺少projectId');
			}
			
			if (!data.branchId) {
				throw new Error('缺少branchId');
			}
			
			if (!data.fromState || !data.toState) {
				throw new Error('缺少状态转换信息');
			}
			
			// 确保状态细节字段
			data.fromLevel1 = data.fromState.level1;
			data.fromLevel2 = data.fromState.level2 || null;
			data.fromLevel3 = data.fromState.level3 || null;
			data.fromLevel4 = data.fromState.level4 || null;
			
			data.toLevel1 = data.toState.level1;
			data.toLevel2 = data.toState.level2 || null;
			data.toLevel3 = data.toState.level3 || null;
			data.toLevel4 = data.toState.level4 || null;
			
			// 设置时间戳
			if (!data.createdTime) data.createdTime = Math.floor(Date.now() / 1000);
			
			// 处理_pid字段
			data._pid = this.PID;
			
			const id = await this.add(data);
			console.log('[addStateHistory] 状态历史记录添加成功，ID:', id);
			return id;
		} catch (err) {
			console.error('[addStateHistory] 添加状态历史记录失败:', err.message || err);
			throw err;
		}
	}
	
	/**
	 * 获取项目的状态历史记录
	 * @param {String} projectId 项目ID
	 * @param {Object} options 选项，如分支ID、分页等
	 * @returns {Promise<Object>} 状态历史记录列表
	 */
	static async getProjectStateHistory(projectId, options = {}) {
		try {
			const query = {
				projectId: projectId
			};
			
			// 如果指定了分支ID，只查询该分支的历史
			if (options.branchId) {
				query.branchId = options.branchId;
			}
			
			// 如果指定了事件类型
			if (options.eventType) {
				query.eventType = options.eventType;
			}
			
			// 设置排序，默认按创建时间倒序
			const orderBy = {
				createdTime: -1
			};
			
			// 设置分页
			let page = options.page || 1;
			let size = options.size || 20;
			
			// 获取总数
			const total = await this.count(query);
			
			if (total === 0) {
				return {
					total: 0,
					list: [],
					page,
					size
				};
			}
			
			// 计算偏移量
			const skip = (page - 1) * size;
			
			// 获取列表数据
			const list = await this.getList(query, '*', orderBy, skip, size);
			
			return {
				total,
				list,
				page,
				size
			};
		} catch (err) {
			console.error('[getProjectStateHistory] 获取项目状态历史失败:', err);
			throw err;
		}
	}
	
	/**
	 * 获取分支的状态历史记录
	 * @param {String} branchId 分支ID
	 * @param {Object} options 选项，如分页等
	 * @returns {Promise<Object>} 状态历史记录列表
	 */
	static async getBranchStateHistory(branchId, options = {}) {
		try {
			const query = {
				branchId: branchId
			};
			
			// 如果指定了事件类型
			if (options.eventType) {
				query.eventType = options.eventType;
			}
			
			// 设置排序，默认按创建时间倒序
			const orderBy = {
				createdTime: -1
			};
			
			// 设置分页
			let page = options.page || 1;
			let size = options.size || 20;
			
			// 获取总数
			const total = await this.count(query);
			
			if (total === 0) {
				return {
					total: 0,
					list: [],
					page,
					size
				};
			}
			
			// 计算偏移量
			const skip = (page - 1) * size;
			
			// 获取列表数据
			const list = await this.getList(query, '*', orderBy, skip, size);
			
			return {
				total,
				list,
				page,
				size
			};
		} catch (err) {
			console.error('[getBranchStateHistory] 获取分支状态历史失败:', err);
			throw err;
		}
	}
	
	/**
	 * 获取特定状态历史记录详情
	 * @param {String} id 历史记录ID
	 * @returns {Promise<Object>} 历史记录详情
	 */
	async getStateHistoryDetail(id) {
		try {
			return await this.getOne({ _id: id });
		} catch (err) {
			console.error('[getStateHistoryDetail] 获取状态历史记录详情失败:', err);
			throw err;
		}
	}
	
	/**
	 * 根据转换前后的状态查找状态流转路径
	 * @param {Object} fromState 起始状态
	 * @param {Object} toState 目标状态
	 * @returns {Promise<Array>} 状态流转路径
	 */
	static async findStateTransitionPath(fromState, toState) {
		try {
			const query = {
				fromLevel1: fromState.level1,
				toLevel1: toState.level1
			};
			
			// 如果指定了二级状态
			if (fromState.level2 && toState.level2) {
				query.fromLevel2 = fromState.level2;
				query.toLevel2 = toState.level2;
			}
			
			// 如果指定了三级状态
			if (fromState.level3 && toState.level3) {
				query.fromLevel3 = fromState.level3;
				query.toLevel3 = toState.level3;
			}
			
			// 按创建时间排序
			const orderBy = {
				createdTime: 1
			};
			
			// 获取记录
			return await this.getAll(query, '*', orderBy);
		} catch (err) {
			console.error('[findStateTransitionPath] 查找状态流转路径失败:', err);
			throw err;
		}
	}
	
	/**
	 * 获取项目的状态流转图数据
	 * @param {String} projectId 项目ID
	 * @returns {Promise<Object>} 状态流转图数据
	 */
	static async getProjectStateFlowData(projectId) {
		try {
			// 获取项目所有状态历史记录
			const historyRecords = await this.getAll({ projectId }, '*', { createdTime: 1 });
			
			if (!historyRecords || historyRecords.length === 0) {
				return {
					nodes: [],
					links: []
				};
			}
			
			// 处理为图数据结构
			const nodes = [];
			const links = [];
			const nodeMap = new Map();
			
			// 构建节点
			historyRecords.forEach(record => {
				// 添加源状态节点
				const fromNodeId = `${record.projectId}_${record.branchId}_${record.fromLevel1}_${record.fromLevel2 || ''}_${record.createdTime - 1}`;
				if (!nodeMap.has(fromNodeId)) {
					nodeMap.set(fromNodeId, {
						id: fromNodeId,
						label: this.getStatusLabel(record.fromState),
						type: 'state',
						branchId: record.branchId,
						level1: record.fromLevel1,
						level2: record.fromLevel2,
						level3: record.fromLevel3,
						level4: record.fromLevel4,
						time: record.createdTime - 1
					});
				}
				
				// 添加目标状态节点
				const toNodeId = `${record.projectId}_${record.branchId}_${record.toLevel1}_${record.toLevel2 || ''}_${record.createdTime}`;
				if (!nodeMap.has(toNodeId)) {
					nodeMap.set(toNodeId, {
						id: toNodeId,
						label: this.getStatusLabel(record.toState),
						type: 'state',
						branchId: record.branchId,
						level1: record.toLevel1,
						level2: record.toLevel2,
						level3: record.toLevel3,
						level4: record.toLevel4,
						time: record.createdTime
					});
				}
				
				// 添加连接
				links.push({
					source: fromNodeId,
					target: toNodeId,
					label: record.eventType,
					data: {
						id: record._id,
						comment: record.comment,
						createdTime: record.createdTime,
						createdBy: record.createdByName
					}
				});
			});
			
			// 将Map转为数组
			nodeMap.forEach(node => {
				nodes.push(node);
			});
			
			return {
				nodes,
				links
			};
		} catch (err) {
			console.error('[getProjectStateFlowData] 获取项目状态流转图数据失败:', err);
			throw err;
		}
	}
	
	/**
	 * 获取状态标签
	 * @param {Object} state 状态对象
	 * @returns {String} 状态标签
	 */
	static getStatusLabel(state) {
		if (!state) return '未知状态';
		
		// 导入ProjectModel以获取状态文本映射
		const ProjectModel = require('./project_model.js');
		const projectModel = new ProjectModel();
		const statusMap = projectModel.getStatusTextMap();
		
		let label = statusMap.level1[state.level1] || '未知';
		
		if (state.level2 && statusMap.level2[state.level1] && statusMap.level2[state.level1][state.level2]) {
			label += ' > ' + statusMap.level2[state.level1][state.level2];
		}
		
		if (state.level3 && statusMap.level3[state.level3]) {
			label += ' > ' + statusMap.level3[state.level3];
		}
		
		if (state.level4 && statusMap.level4[state.level3] && statusMap.level4[state.level3][state.level4]) {
			label += ' > ' + statusMap.level4[state.level3][state.level4];
		}
		
		return label;
	}
}

module.exports = ProjectStateHistoryModel; 